#ifndef MOUSSAVI_INTERNALS_H_
#define MOUSSAVI_INTERNALS_H_

#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <ctype.h>
#include <stdlib.h>

#include "freakusb.h"
#include "types.h"
#include "DataFlash.h"
#include "Moussavi_transfer_protocol.h"
#include "Moussavi_file_system.h"


#define MOUSSAVI_VER			1
#define MOUSSAVI_SUBVER			7
#define MOUSSAVI_MEMORY_SIZE	32
#define MOUSSAVI_CLOCK_SPEED	16
#define MOUSSAVI_NUM_LEDS		64
#define MOUSSAVI_IS_RGB			1
#define MOUSSAVI_COLOR_DEPTH	2


// Port Definitions
#define DD_MOSI			PB2
#define DD_MISO			PB3
#define DD_SCK			PB1
#define DD_SS			PB0
#define DD_PORT			PORTB
#define DDR_SPI 		DDRB

// Macros
#define TWO_INDEXES 	asm ( "mov r17, r16" );	asm ( "swap r16" );	asm ( "andi r16, 0xF" ); asm ( "andi r17, 0xF" );
#define CS_UP			DD_PORT |= _BV(DD_SS)
#define CS_DOWN			DD_PORT &= ~(_BV(DD_SS))

#define ROW_PORT		PORTA
#define ROW_PORT_DIR	DDRA

#define		SET_BUFFERREADY		GPIOR0 |= 0b00100000;
#define		UNSET_BUFFERREADY	GPIOR0 &= 0b11011111;
#define		BUFFER_IS_READY		(GPIOR0 & 0b00100000)

#define		SET_HIGHSPEED		GPIOR0 |= 0b10000000;
#define		UNSET_HIGHSPEED		GPIOR0 &= 0b01111111;
#define		IS_HIGHSPEED		(GPIOR0 & 0b10000000)

#define		SET_FIRST_BUFFER	GPIOR0 &= 0b10111111;
#define		SET_SECOND_BUFFER	GPIOR0 |= 0b01000000;
#define		WHICH_BUFFER		(GPIOR0 & 0b01000000)

#define		SET_ROW(r)			GPIOR0 &= 0b11110000; GPIOR0 |= r;
#define		ADVANCE_ROW			GPIOR0 = (GPIOR0 + 1)&(0b11100111); GPIOR2 = 0; GPIOR2 = (1<<(GPIOR0 & 0b00000111));
#define		ROW_NUM				(GPIOR0 & 0b00000111)

#define		PWM_COUNTER			GPIOR1
#define		ADVANCE_COUNTER		GPIOR1 = (GPIOR1 + 1)&(0b00000011);

#define		ROW_PATTERN			GPIOR2

#define		READ_FLASH_BYTE		{SPDR = 0; while (! (SPSR & (1<<SPIF))){}}

// MSB 4 is L2
// LSB 4 is L1
#define		UNIFY8TO44 ( L1, L2 )	((L2)<<4)|((L1)&0b00001111)

#endif // MOUSSAVI_INTERNALS_H_
